package com.studerb.model;

import java.util.ArrayList;
import java.util.List;
import java.util.SortedSet;
import java.util.TreeSet;

import org.apache.log4j.Logger;

import com.studerb.service.ParsedSubject;

public class HeaderThread extends Post {
	private static Logger logger = Logger.getLogger(HeaderThread.class);

	protected Integer maxPart;
	protected Boolean zeroIndexed = false;
	protected SortedSet<Header> headers = new TreeSet<Header>(new HeaderComparator());
	protected List<Long> headerArticles = new ArrayList<Long>();
	protected Boolean complete = false;

	public HeaderThread() {}

	public HeaderThread(Header header, ParsedSubject parsedSubject) {
		newsGroup = header.getNewsGroup();
		subject = parsedSubject.getThreadedSubject();
		maxPart = parsedSubject.getMaxPart();
		author = header.getAuthor();
	}

	public void addHeader(Header header) {
		int current = header.getCurrentPart();

		if (current > maxPart) {
			throw new RuntimeException(String.format(header.getSubject() + "  adding %d to thread with max length of %d", current, maxPart));
		}
		if (current == 0) {
			zeroIndexed = true;
		}

		if (headerArticles.contains(current)) {
			throw new RuntimeException(String.format(header.getSubject() + "  adding duplicate articleNumber: ", current));
		}

		if (!author.equals(header.getAuthor())) {
			logger.warn("Author Mismatch: " + author + " / " + header.getAuthor());
		}

		if (datePosted == null || datePosted.compareTo(header.getDatePosted()) > 0) {
			datePosted = header.getDatePosted();
		}
		if (articleNumber == null || articleNumber.compareTo(header.getArticleNumber()) > 0) {
			articleNumber = header.getArticleNumber();
		}

		byteCount = byteCount == null ? header.getByteCount() : byteCount + header.getByteCount();

		headerArticles.add(header.getArticleNumber());
		complete = checkComplete();
	}

	private boolean checkComplete() {
		if (zeroIndexed && headerArticles.size() == maxPart + 1) {
			return true;
		}
		else if (headerArticles.size() == maxPart) {
			return true;
		}
		else {
			return false;
		}

	}

	@Override public boolean equals(Object obj) {
		if (this == obj) {
			return true;
		}
		if (!super.equals(obj)) {
			return false;
		}
		if (getClass() != obj.getClass()) {
			return false;
		}
		HeaderThread other = (HeaderThread) obj;
		if (subject == null) {
			if (other.subject != null) {
				return false;
			}
		}
		else if (!subject.equals(other.subject)) {
			return false;
		}
		return true;
	}

	public List<Long> getHeaderArticles() {
		return headerArticles;
	}

	public SortedSet<Header> getHeaders() {
		return headers;
	}

	public Integer getMaxPart() {
		return maxPart;
	}

	public Boolean getZeroIndexed() {
		return zeroIndexed;
	}

	@Override public int hashCode() {
		final int prime = 31;
		int result = super.hashCode();
		result = prime * result + (subject == null ? 0 : subject.hashCode());
		return result;
	}

	public Boolean isComplete() {
		return complete;
	}

	public boolean isZeroIndexed() {
		return zeroIndexed;
	}

	public void setComplete(Boolean complete) {
		this.complete = complete;
	}

	public void setHeaderArticles(List<Long> headerArticles) {
		this.headerArticles = headerArticles;
	}

	public void setHeaders(SortedSet<Header> headers) {
		this.headers = headers;
	}

	public void setMaxPart(Integer maxPart) {
		this.maxPart = maxPart;
	}

	public void setZeroIndexed(Boolean zeroIndexed) {
		this.zeroIndexed = zeroIndexed;
	}

	@Override public String toString() {
		StringBuffer buffer = new StringBuffer();
		buffer.append("Threaded: " + subject + ": " + maxPart + " parts");
		return buffer.toString();
	}
}
